package com.yaolong.api.modules.gen.service.impl;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.TemplateType;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.fill.Column;
import com.baomidou.mybatisplus.generator.fill.Property;
import com.yaolong.api.configuration.properties.CodeGenProperties;
import com.yaolong.api.modules.gen.config.CustomConfigs;
import com.yaolong.api.modules.gen.config.CustomControllerStrategyConfig;
import com.yaolong.api.modules.gen.config.CustomFileConfig;
import com.yaolong.api.modules.gen.config.CustomGlobalConfig;
import com.yaolong.api.modules.gen.config.CustomOutputTemplateResultConfig;
import com.yaolong.api.modules.gen.config.CustomTemplateConfig;
import com.yaolong.api.modules.gen.config.MybatisPlusBasicTemplateGenConfig;
import com.yaolong.api.modules.gen.constants.GenConstants;
import com.yaolong.api.modules.gen.genengines.CustomAbstractTemplateEngine;
import com.yaolong.api.modules.gen.genengines.CustomBeetlTemplateEngine;
import com.yaolong.api.modules.gen.genengines.CustomFreemarkerTemplateEngine;
import com.yaolong.api.modules.gen.genengines.CustomVelocityTemplateEngine;
import com.yaolong.api.modules.gen.model.dto.GenCodePreviewDto;
import com.yaolong.api.modules.gen.model.dto.TemplateDetailDto;
import com.yaolong.api.modules.gen.service.IGenCodeService;
import com.yaolong.api.modules.gen.service.ITemplateFileService;
import com.yaolong.api.modules.gen.utils.MybatisPlusCodeGenUtil;
import com.yaolong.api.modules.gen.vo.CodeGenConfigVo;
import com.yaolong.api.modules.gen.vo.GenBaseConfigEntity;
import com.yaolong.api.modules.gen.vo.GenDataSourceConfigEntity;
import com.yaolong.api.modules.gen.vo.GenTableConfigEntity;
import com.yaolong.api.modules.sys.domain.SysMenuMeta;
import com.yaolong.api.modules.sys.domain.SysMenuResource;
import com.yaolong.api.modules.sys.domain.SysPermission;
import com.yaolong.api.modules.sys.service.ISysMenuMetaService;
import com.yaolong.api.modules.sys.service.ISysMenuResourceService;
import com.yaolong.api.modules.sys.service.ISysPermissionService;
import com.yaolong.commons.base2.BaseController;
import com.yaolong.commons.base2.BaseDomain;
import com.yaolong.commons.base2.BaseServiceImpl;
import com.yaolong.commons.base2.IBaseService;
import com.yaolong.commons.exceptions.BusinessException;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author yaolong
 * @version V1.0.0
 * @program AgileFastFK3.0
 * @description 代码生成实现类
 * @create 2022-12-31 15:15
 **/
@Service
public class GenCodeServiceImpl implements IGenCodeService {

    @Resource
    ITemplateFileService templateFileService;

    @Resource
    CodeGenProperties codeGenProperties;

    @Resource
    ISysMenuMetaService sysMenuMetaService;

    @Resource
    ISysMenuResourceService sysMenuResourceService;

    @Resource
    ISysPermissionService sysPermissionService;

    @Override
    public boolean  genCode(CodeGenConfigVo configVo) {
        configVo.getGenBaseConfigEntity().setOutputType(GenConstants.OUTPUT_TYPE_FILE);
        try {
            baseGen(configVo);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            throw new BusinessException("代码生成异常，请检查配置");
        }
    }

    @Override
    public GenCodePreviewDto previewGenCode(CodeGenConfigVo configVo) {
        //设置输出类型为字符串
        configVo.getGenBaseConfigEntity().setOutputType(GenConstants.OUTPUT_TYPE_STRING);
        try {
            CustomOutputTemplateResultConfig resultConfig = baseGen(configVo);
            GenCodePreviewDto genCodePreviewDto = new GenCodePreviewDto();
            genCodePreviewDto.setFrontEndCode(resultConfig.getFrontEndCode());
            genCodePreviewDto.setOtherCode(resultConfig.getOtherCode());
            genCodePreviewDto.setSqlCode(resultConfig.getSqlCode());
            genCodePreviewDto.setAfterEndCode(resultConfig.getAfterEndCode());
            return genCodePreviewDto;
        }catch (Exception e){
            e.printStackTrace();
            throw new BusinessException("代码生成异常，请检查配置");
        }
    }


    private CustomOutputTemplateResultConfig baseGen(CodeGenConfigVo genConfig) {
        //注入模板结果配置-当代码生成完成后该结果配置中会被设置文件生成的结果
        CustomOutputTemplateResultConfig customOutputTemplateResultConfig = new CustomOutputTemplateResultConfig();

        // 查询系统表中的最后一个菜单id并设置进去
        // 获取mysql最新id
        SysMenuMeta lastMeta = sysMenuMetaService.lambdaQuery().orderByDesc(SysMenuMeta::getId).last("limit 1").one();
        SysMenuResource lastMenu = sysMenuResourceService.lambdaQuery().orderByDesc(SysMenuResource::getId).last("limit 1").one();
        SysPermission lastPermission = sysPermissionService.lambdaQuery().orderByDesc(SysPermission::getId).last("limit 1").one();
        customOutputTemplateResultConfig.setCurrentMysqlMenuId(lastMenu.getId().intValue());
        customOutputTemplateResultConfig.setCurrentMysqlMenuMetaId(lastMeta.getId().intValue());
        customOutputTemplateResultConfig.setCurrentPermissionId(lastPermission.getId().intValue());
        // TODO Oracle 暂时不支持 因为系统表是MySQL的，后续再来解决动态数据源问题
        customOutputTemplateResultConfig.setCurrentOracleMenuId(0);
        customOutputTemplateResultConfig.setCurrentOracleMenuMetaId(0);

        GenBaseConfigEntity genBaseConfigEntity = genConfig.getGenBaseConfigEntity();
        GenDataSourceConfigEntity genDataSourceEntity = genConfig.getGenDataSourceEntity();
        List<GenTableConfigEntity> genTableConfigs = genConfig.getGenTableConfigs();

        //当前模板组中的模板
        Long templateGroupId = genBaseConfigEntity.getTemplateGroupId();
        List<TemplateDetailDto> templateDetailsList = templateFileService.getTemplateDetailsList(new TemplateDetailDto().setGroupId(templateGroupId));
        //设置文件总数
        customOutputTemplateResultConfig.setFileTotalCount(templateDetailsList.size() * genTableConfigs.size());

        //将数据库的模板分类
        Map<String, List<TemplateDetailDto>> tplMap = getTplMap(templateDetailsList);
        //生成不同模板的
        tplMap.forEach((engine, tpl) -> {
            CustomAbstractTemplateEngine templateEngine = getTemplateEngine(engine);
            if (tpl.size()>0){
                //根据当前的模板批量生成，这里的集合个数相当于表个数，遍历生成
                genTableConfigs.forEach(genTableConfigEntity -> {

                    //=========================================================公共配置-BEGIN==========================================
                    //数据源配置
                    DataSourceConfig dataSourceConfig = new DataSourceConfig.Builder(genDataSourceEntity.getDbUrl(), genDataSourceEntity.getDbUserName(), genDataSourceEntity.getDbPassword())
                            .dbQuery(MybatisPlusCodeGenUtil.getDbQuery(genDataSourceEntity.getDbType()))
                            .build();
                    AutoGenerator autoGenerator = new AutoGenerator(dataSourceConfig);
                    //初始化全局配置
                    initGlobalConfig(genBaseConfigEntity, autoGenerator);
                    //初始化包配置
                    initPackageConfig(genBaseConfigEntity, autoGenerator, templateDetailsList);
                    //=========================================================公共配置--END==========================================

                    //初始化模板配置
                    initTemplateConfig(autoGenerator, tpl);
                    if (!ObjectUtils.isEmpty(templateEngine)) {
                        //=========================================================templateEngine特例配置--BEGIN==========================================
                        //初始化自定义配置
                        initCustomConfig(genBaseConfigEntity, autoGenerator, genTableConfigEntity, tpl, customOutputTemplateResultConfig);
                        //初始化策略配置
                        initStrategyConfig(genBaseConfigEntity, genDataSourceEntity, autoGenerator, genTableConfigEntity,tpl);
                        //=========================================================templateEngine特例配置--END==========================================

                        //根据引擎不同生成不同的模板代码
                        autoGenerator.execute(templateEngine);

                    }
                });
            }
        });

        //生成成功后会设置值到该结果配置中，这里直接返回
        return customOutputTemplateResultConfig;
    }

    /**
     * <p>
     * 从数据库查询出来的模板中提取mybatisplus基本生成类型
     * </p>
     * @version 1.0.0 <br>
     * @date 2022/12/31 17:13 <br>
     * @author yaolonga <br>
     * @param templateDetailsList
     * @return com.yaolong.api.modules.gen.config.MybatisPlusBasicTemplateGenConfig
     */
    private MybatisPlusBasicTemplateGenConfig getMybatisPlusBasicTemplateGenConfigFromDBTpl(List<TemplateDetailDto> templateDetailsList){
        TemplateDetailDto service = getTemplate(templateDetailsList, GenConstants.GEN_TEMPLATE_SERVICE_TYPE);
        TemplateDetailDto entity = getTemplate(templateDetailsList, GenConstants.GEN_TEMPLATE_ENTITY_TYPE);
        TemplateDetailDto controller = getTemplate(templateDetailsList, GenConstants.GEN_TEMPLATE_CONTROLLER_TYPE);
        TemplateDetailDto serviceImpl = getTemplate(templateDetailsList, GenConstants.GEN_TEMPLATE_SERVICE_IMPL_TYPE);
        TemplateDetailDto mapper = getTemplate(templateDetailsList, GenConstants.GEN_TEMPLATE_MAPPER_TYPE);
        TemplateDetailDto dao = getTemplate(templateDetailsList, GenConstants.GEN_TEMPLATE_DAO_TYPE);

        MybatisPlusBasicTemplateGenConfig mybatisPlusBasicTemplateGenConfig = new MybatisPlusBasicTemplateGenConfig();
        mybatisPlusBasicTemplateGenConfig.setService(service);
        mybatisPlusBasicTemplateGenConfig.setEntity(entity);
        mybatisPlusBasicTemplateGenConfig.setServiceImpl(serviceImpl);
        mybatisPlusBasicTemplateGenConfig.setController(controller);
        mybatisPlusBasicTemplateGenConfig.setDao(dao);
        mybatisPlusBasicTemplateGenConfig.setMapper(mapper);
        return mybatisPlusBasicTemplateGenConfig;
    }

    @NotNull
    private CustomAbstractTemplateEngine getTemplateEngine(String key) {
        //模板引擎配置
        CustomAbstractTemplateEngine templateEngine = null;
        switch (key) {
            case GenConstants.TEMPLATE_ENGINE_FREEMARKER:
                templateEngine = new CustomFreemarkerTemplateEngine();
                break;
            case GenConstants.TEMPLATE_ENGINE_VELOCITY:
                templateEngine = new CustomVelocityTemplateEngine();
                break;
            case GenConstants.TEMPLATE_ENGINE_BEETL:
                templateEngine = new CustomBeetlTemplateEngine();
                break;
            default:
                throw new BusinessException(String.format("不支持当前引擎 %s 请联系管理员适配", key));
        }
        return templateEngine;
    }


    /**
     * <p>
     * 模板分类
     * </p>
     *
     * @param templateDetailsList
     * @return java.util.Map<java.lang.String, java.util.List < com.yaolong.api.modules.gen.model.dto.TemplateDetailDto>>
     * @version 1.0.0 <br>
     * @date 2022/12/31 14:03 <br>
     * @author yaolonga <br>
     */
    private Map<String, List<TemplateDetailDto>> getTplMap(List<TemplateDetailDto> templateDetailsList) {
        //目前只支持这三中模板引擎
        List<TemplateDetailDto> ftls = templateDetailsList.stream().filter(td -> td.getTemplateType().equals(GenConstants.TEMPLATE_ENGINE_FREEMARKER)).collect(Collectors.toList());
        List<TemplateDetailDto> beetls = templateDetailsList.stream().filter(td -> td.getTemplateType().equals(GenConstants.TEMPLATE_ENGINE_BEETL)).collect(Collectors.toList());
        List<TemplateDetailDto> vtls = templateDetailsList.stream().filter(td -> td.getTemplateType().equals(GenConstants.TEMPLATE_ENGINE_VELOCITY)).collect(Collectors.toList());

        Map<String, List<TemplateDetailDto>> templateFile = new HashMap<>();
        templateFile.put(GenConstants.TEMPLATE_ENGINE_FREEMARKER, ftls);
        templateFile.put(GenConstants.TEMPLATE_ENGINE_BEETL, beetls);
        templateFile.put(GenConstants.TEMPLATE_ENGINE_VELOCITY, vtls);
        return templateFile;
    }

    private void initCustomConfig(GenBaseConfigEntity genBaseConfigEntity, AutoGenerator autoGenerator, GenTableConfigEntity genTableConfigEntity, List<TemplateDetailDto> ftls, CustomOutputTemplateResultConfig templateResultConfig) {
        //自定义配置
        CustomConfigs customConfigs = new CustomConfigs();


        //注入自定义配置
        //自定义全局配置
        CustomGlobalConfig customGlobalConfig = new CustomGlobalConfig();
        customGlobalConfig.setOutputType(genBaseConfigEntity.getOutputType());
        customGlobalConfig.setGenMode(genBaseConfigEntity.getGenMode());
        customGlobalConfig.setZipName(genBaseConfigEntity.getZipName());
        customGlobalConfig.setVersion(genBaseConfigEntity.getVersion());
        customGlobalConfig.setModuleNameZh(genBaseConfigEntity.getModuleNameZh());
        customConfigs.setCustomGlobalConfig(customGlobalConfig);


        //自定义模板配置
        CustomTemplateConfig customTemplateConfig = new CustomTemplateConfig();
        customTemplateConfig.setEnableDbTemplate(true);
        //自定义controller策略配置
        CustomControllerStrategyConfig customControllerStrategyConfig = new CustomControllerStrategyConfig();
        customControllerStrategyConfig.setApiPrefix(genBaseConfigEntity.getApiPrefix());
        customConfigs.setCustomControllerStrategyConfig(customControllerStrategyConfig);


        Map<String, String> customFile = new HashMap<>();
        Map<String, String> stringTemplates = new HashMap<>();

        //过滤基本的模板生成类型
        ftls.stream().filter(tpl -> {
            String templateFilePath = tpl.getTemplateFilePath();
            String templateGenType = tpl.getTemplateGenType();
            List<String> templateGenTypes = Arrays.asList(
                    GenConstants.GEN_TEMPLATE_DAO_TYPE,
                    GenConstants.GEN_TEMPLATE_MAPPER_TYPE,
                    GenConstants.GEN_TEMPLATE_SERVICE_IMPL_TYPE,
                    GenConstants.GEN_TEMPLATE_SERVICE_TYPE,
                    GenConstants.GEN_TEMPLATE_CONTROLLER_TYPE,
                    GenConstants.GEN_TEMPLATE_ENTITY_TYPE
            );
            if (!ObjectUtils.isEmpty(templateFilePath) && templateGenTypes.contains(templateGenType)){
                return false;
            }
            return true;
        }).forEach(templateDetailDto -> {
            //设置自定义文件
            String templateFile = templateDetailDto.getTemplateFile();
            String templateFilePath = templateDetailDto.getTemplateFilePath();
            //如果templateFile和templateFilePath同时存在默认值处理templateFile
            if (!ObjectUtils.isEmpty(templateFile)){
                customFile.put(
                        templateDetailDto.getFileName(),
                        GenConstants.TEMPLATE_DB_TYPE +
                        GenConstants.TEMPLATE_TYPE_SEPARATOR +
                        templateDetailDto.getTemplateName() +
                        GenConstants.TEMPLATE_TYPE_SEPARATOR +
                        templateDetailDto.getTemplatePath() +
                        GenConstants.TEMPLATE_TYPE_SEPARATOR +
                        templateDetailDto.getTemplateFileType()
                );
                //设置字符串模板
                stringTemplates.put(templateDetailDto.getTemplateName(), templateFile);
            } else if (!ObjectUtils.isEmpty(templateFilePath)){
                customFile.put(templateDetailDto.getFileName(),
                        //数据库前缀标识
                        GenConstants.TEMPLATE_DB_TYPE +
                        GenConstants.TEMPLATE_TYPE_SEPARATOR +
                        //模板名称
                        templateDetailDto.getTemplateName() +
                        GenConstants.TEMPLATE_TYPE_SEPARATOR +
                        //模板基于父配置的生成路径
                        templateDetailDto.getTemplatePath() +
                        GenConstants.TEMPLATE_TYPE_SEPARATOR +
                        //文件所属类型 java类的还是vue类的文件
                        templateDetailDto.getTemplateFileType()+
                        GenConstants.TEMPLATE_TYPE_SEPARATOR +
                        //文件地址
                        templateDetailDto.getTemplateFilePath()
                );
            }
        });

        customTemplateConfig.setStringTemplates(stringTemplates);
        customConfigs.setCustomTemplateConfig(customTemplateConfig);


        //设置CustomFileConfig
        CustomFileConfig customFileConfig = new CustomFileConfig();
        customFileConfig.setVueParentPath(getOutputDir(genBaseConfigEntity.getFrontEndParentPath(), ""));
        customFileConfig.setSqlParentPath(getOutputDir(genBaseConfigEntity.getSqlParentPath(), ""));
        customFileConfig.setOtherParentPath(getOutputDir(genBaseConfigEntity.getOtherParentPath(), ""));
        customFileConfig.setJavaParentPath(getOutputDir(genBaseConfigEntity.getAfterEndParentPath(), ""));

        //把当前表的配置全部注入
        customFileConfig.setGenTableConfigEntity(genTableConfigEntity);
        customConfigs.setCustomFileConfig(customFileConfig);
        customConfigs.setCustomOutputTemplateResultConfig(templateResultConfig);


        //注入配置
        InjectionConfig injectionConfig = new InjectionConfig.Builder()
                .customMap(Collections.singletonMap(GenConstants.CUSTOM_CONFIG_FIELD, customConfigs))
                .customFile(customFile)
                .fileOverride()
                .build();
        autoGenerator.injection(injectionConfig);
    }

    /**
     * 策略配置初始化
     */
    private void initStrategyConfig(GenBaseConfigEntity genBaseConfigEntity, GenDataSourceConfigEntity genDataSourceEntity, AutoGenerator autoGenerator, GenTableConfigEntity genTableConfigEntity, List<TemplateDetailDto> tpls) {

        //获取固定配置
        MybatisPlusBasicTemplateGenConfig config = getMybatisPlusBasicTemplateGenConfigFromDBTpl(tpls);

        StrategyConfig.Builder builder = new StrategyConfig.Builder();
        if (genBaseConfigEntity.getRemoveTablePrefix() && !ObjectUtils.isEmpty(genBaseConfigEntity.getTablePrefixName())){
            builder.addTablePrefix(genBaseConfigEntity.getTablePrefixName());

        }

        StrategyConfig strategyConfig = builder
                .enableSchema()
                .addInclude(genTableConfigEntity.getTableName())

                //实体策略
                .entityBuilder()
                .fileOverride()
                .superClass(BaseDomain.class)
//                .disableSerialVersionUID()
                .enableChainModel()
                .enableLombok()
//                .enableRemoveIsPrefix()
                .enableTableFieldAnnotation()
//                .enableActiveRecord()
//                .versionColumnName("version")
//                .versionPropertyName("version")
//                .logicDeleteColumnName("deleted")
//                .logicDeletePropertyName("deleteFlag")
                .naming(NamingStrategy.underline_to_camel)
                .columnNaming(NamingStrategy.underline_to_camel)
                .addSuperEntityColumns(codeGenProperties.getSuperEntityColumns())
                .addTableFills(new Column("Date_Created", FieldFill.INSERT))
                .addTableFills(new Property("Date_Modified", FieldFill.INSERT_UPDATE))
                .idType(ObjectUtils.isEmpty(genBaseConfigEntity.getIdType()) ? genBaseConfigEntity.getIdType() : IdType.AUTO)
                .formatFileName(getFormat(config.getEntity()))

                //controller策略
                .controllerBuilder()
                .fileOverride()
                .superClass(BaseController.class)
                .enableHyphenStyle()
                .enableRestStyle()
                .formatFileName(ObjectUtils.isEmpty(getFormat(config.getController())) ? "%sController" : Objects.requireNonNull(getFormat(config.getController())))

                //Service策略
                .serviceBuilder()
                .fileOverride()
                .superServiceClass(IBaseService.class)
                .superServiceImplClass(BaseServiceImpl.class)
                .formatServiceFileName(ObjectUtils.isEmpty(getFormat(config.getService())) ? "I%sService" : Objects.requireNonNull(getFormat(config.getService())))
                .formatServiceImplFileName(ObjectUtils.isEmpty(getFormat(config.getServiceImpl())) ? "%sServiceImpl" : Objects.requireNonNull(getFormat(config.getServiceImpl())))

                //mapper策略
                .mapperBuilder()
                .fileOverride()
                .superClass(BaseMapper.class)
                .enableMapperAnnotation()
                .enableBaseResultMap()
                .enableBaseColumnList()
                .formatMapperFileName(ObjectUtils.isEmpty(getFormat(config.getDao())) ? "%sDao" : Objects.requireNonNull(getFormat(config.getDao())))
                .formatXmlFileName(ObjectUtils.isEmpty(getFormat(config.getMapper())) ? "%sDao" : Objects.requireNonNull(getFormat(config.getMapper())))
                .build();
        autoGenerator.strategy(strategyConfig);
    }

    /**
     * 格式化文件名
     */
    private String getFormat(TemplateDetailDto serviceImpl) {
        if (ObjectUtils.isEmpty(serviceImpl)){
            return null;
        }
        return serviceImpl.getFileName().split("\\.")[0];
    }

    /**
     * <p>
     * 初始化固定模板
     * </p>
     *
     * @param autoGenerator
     * @param tpls
     * @return void
     * @version 1.0.0 <br>
     * @date 2022/12/31 15:30 <br>
     * @author yaolonga <br>
     */
    private void initTemplateConfig(AutoGenerator autoGenerator, List<TemplateDetailDto> tpls) {
        MybatisPlusBasicTemplateGenConfig config = getMybatisPlusBasicTemplateGenConfigFromDBTpl(tpls);
        TemplateDetailDto entity = config.getEntity();
        TemplateDetailDto serviceImpl = config.getServiceImpl();
        TemplateDetailDto service = config.getService();
        TemplateDetailDto dao = config.getDao();
        TemplateDetailDto mapper = config.getMapper();
        TemplateDetailDto controller = config.getController();

        //模板配置
        TemplateConfig.Builder templateConfigBuilder = new TemplateConfig.Builder();
        //禁用自带的模板
        templateConfigBuilder
                .disable(TemplateType.ENTITY)
                .disable(TemplateType.CONTROLLER)
                .disable(TemplateType.SERVICE)
                .disable(TemplateType.SERVICEIMPL)
                .disable(TemplateType.MAPPER)
                .disable(TemplateType.XML);

        //设置service、dao、controller、serviceImpl、mapper模板配置
        if (!ObjectUtils.isEmpty(entity) && !ObjectUtils.isEmpty(entity.getTemplateFilePath())) {
            templateConfigBuilder.entity(entity.getTemplateFilePath());
        }
        if (!ObjectUtils.isEmpty(controller) && !ObjectUtils.isEmpty(controller.getTemplateFilePath())) {
            templateConfigBuilder.controller(controller.getTemplateFilePath());
        }
        if (!ObjectUtils.isEmpty(service) && !ObjectUtils.isEmpty(service.getTemplateFilePath())) {
            templateConfigBuilder.service(service.getTemplateFilePath());
        }
        if (!ObjectUtils.isEmpty(mapper) && !ObjectUtils.isEmpty(mapper.getTemplateFilePath())) {
            templateConfigBuilder.xml(mapper.getTemplateFilePath());
        }
        if (!ObjectUtils.isEmpty(dao) && !ObjectUtils.isEmpty(dao.getTemplateFilePath())) {
            templateConfigBuilder.mapper(dao.getTemplateFilePath());
        }
        if (!ObjectUtils.isEmpty(serviceImpl) && !ObjectUtils.isEmpty(serviceImpl.getTemplateFilePath())) {
            templateConfigBuilder.serviceImpl(serviceImpl.getTemplateFilePath());
        }
        autoGenerator.template(templateConfigBuilder.build());
    }

    /**
     * 获取模板-取模板列表的最后一个
     */
    private TemplateDetailDto getTemplate(List<TemplateDetailDto> templateDetailsList, String templateGentype) {
        List<TemplateDetailDto> services = templateDetailsList.stream().filter(td -> td.getTemplateGenType().equals(templateGentype)).collect(Collectors.toList());
        if (services.size()>0){
            return services.get(services.size() - 1);
        }
        return null;
    }

    /**
     * <p>
     * 初始化包配置
     * </p>
     *
     * @param genBaseConfigEntity
     * @param autoGenerator
     * @param tpls 当前要生成的模板
     * @return void
     * @version 1.0.0 <br>
     * @date 2022/12/31 15:30 <br>
     * @author yaolonga <br>
     */
    private void initPackageConfig(GenBaseConfigEntity genBaseConfigEntity, AutoGenerator autoGenerator,List<TemplateDetailDto> tpls) {
        MybatisPlusBasicTemplateGenConfig config = getMybatisPlusBasicTemplateGenConfigFromDBTpl(tpls);
        TemplateDetailDto entity = config.getEntity();
        TemplateDetailDto serviceImpl = config.getServiceImpl();
        TemplateDetailDto service = config.getService();
        TemplateDetailDto dao = config.getDao();
        TemplateDetailDto mapper = config.getMapper();
        TemplateDetailDto controller = config.getController();

        //包配置
        PackageConfig.Builder packageConfigBuilder = new PackageConfig.Builder();
        packageConfigBuilder
                .parent(genBaseConfigEntity.getPackageName())
                .moduleName(genBaseConfigEntity.getModuleName());
        //默认生成配置
        packageConfigBuilder
                .entity("model.entity")
                .service("service")
                .serviceImpl("service.impl")
                .mapper("dao")
                .xml("mapper.xml")
                .controller("controller")
                .pathInfo(Collections.singletonMap(OutputFile.xml, getOutputDir(genBaseConfigEntity.getAfterEndParentPath(), "/resources/mapper/" + genBaseConfigEntity.getModuleName())));


        if (!ObjectUtils.isEmpty(service)) {
            packageConfigBuilder.service(path2PackageName(service));
        }
        if (!ObjectUtils.isEmpty(entity)) {
            packageConfigBuilder.entity(path2PackageName(entity));
        }
        if (!ObjectUtils.isEmpty(serviceImpl)) {
            packageConfigBuilder.serviceImpl(path2PackageName(serviceImpl));
        }
        if (!ObjectUtils.isEmpty(controller)) {
            packageConfigBuilder.controller(path2PackageName(controller));
        }
        if (!ObjectUtils.isEmpty(mapper)) {
            packageConfigBuilder.xml(path2PackageName(mapper));
        }
        if (!ObjectUtils.isEmpty(dao)) {
            packageConfigBuilder.mapper(path2PackageName(dao));
        }
        autoGenerator.packageInfo(packageConfigBuilder.build());
    }

    /**
     * <p>
     * 路径转包名
     * </p>
     * @version 1.0.0 <br>
     * @date 2022/12/31 16:19 <br>
     * @author yaolonga <br>
     * @param service
     * @return java.lang.String
     */
    @NotNull
    private String path2PackageName(TemplateDetailDto service) {
        List<String> strings = Arrays.asList("/","\\");
        String startChar = service.getTemplatePath().substring(0, 1);
        if (strings.contains(startChar)){
            return service.getTemplatePath().replace("\\", ".").substring(1);
        }
        return service.getTemplatePath().replace("\\", ".");
    }


    /**
     * <p>
     * 初始化全局配置
     * </p>
     *
     * @param genBaseConfigEntity
     * @param autoGenerator
     * @return void
     * @version 1.0.0 <br>
     * @date 2022/12/31 0:04 <br>
     * @author yaolonga <br>
     */
    private void initGlobalConfig(GenBaseConfigEntity genBaseConfigEntity, AutoGenerator autoGenerator) {
        //全局配置
        GlobalConfig.Builder globalConfigBuilder = new GlobalConfig.Builder();


        String outputDir = getOutputDir(genBaseConfigEntity.getAfterEndParentPath(), "/java");

        GlobalConfig globalConfig = globalConfigBuilder.outputDir(outputDir)
                .author(genBaseConfigEntity.getAuthor())
                .enableSwagger()
                .disableOpenDir()
                .dateType(DateType.TIME_PACK)
                .commentDate("yyyy-MM-dd")
                .build();
        autoGenerator.global(globalConfig);
    }

    private String getOutputDir(String parentPath, String suffix) {
        String outputDir = System.getProperty("user.dir") + "/" + parentPath + suffix;
        if (parentPath.startsWith("/") || parentPath.matches(GenConstants.DRIVE_REGEX)) {
            //linux路径根路径和windos绝对路径直接tihuan
            outputDir = parentPath;
        }
        return outputDir;
    }




}
